/**************************************************************************************
*
*	Copyright (C) 2009 - 2012 Brent Andrew O. Chua - See LICENSE.txt for more info.
*		
*	Filename	-	Effect.h
*
*	Description -	
*
*	Comments	-	
*
*	Modification History:
*			Name			   Date					Description
*			MrCodeSushi	-	06/05/2012	-	Creation of this file
**************************************************************************************/
#ifndef _PSX_RENDER_TECHINIQUE_H_
#define _PSX_RENDER_TECHINIQUE_H_

#include "PulseSTD.h"
#include "RenderPass.h"
#include "ResourcePoolItem.h"
#include "StoragePool.h"
#include "String.h"
#include "RenderTechnique.h"
#include "GeometryElementRequirement.h"
#include "MaterialElementRequirement.h"

namespace Pulse
{
	typedef U16 EffectID;

	struct EffectDesc : public BaseResDesc
	{
	public:

		EffectDesc( void ) { }

		EffectDesc( const CHAR *pFilename ) { SetToLoad( pFilename ); }

		void SetEffect( const CHAR *pDescription ) { m_description = pDescription;  }

		void SetToLoad( const CHAR *pFilename ) { m_filename = pFilename; }

		virtual const ResourceCode GetType( void ) const { return ResourceCode( EResource::VIDEO, EVideoResource::EFFECT ); }

		String		m_filename;
		String		m_name;
		String		m_description;
	};

	class Effect : public IResourcePoolItem
	{
	public:

		virtual ~Effect( void );

		// These defines the base interface for all derived resources
		virtual BOOL CreateResource( BaseResDesc *pDesc );
		virtual BOOL DestroyResource( void );
		virtual BOOL LoadResource( void );	
		virtual BOOL UnloadResource( void );

		EffectDesc * GetDescription( void ) { return &m_desc; }

		virtual const ResourceCode GetType( void ) const { return ResourceCode( EResource::VIDEO, EVideoResource::EFFECT ); }

		void RegisterTechnique( RenderTechnique *pTech, TechniquePriority priority );

		RenderTechnique * GetTechnique( void );

		const SIZE_T GetNumGeometryRequirements( void ) const { return m_geometryRequirements.GetSize(); }

		GeometryElementRequirement * GetGeometryRequirements( void );

		const SIZE_T GetNumMaterialRequirements( void ) const { return m_materialRequirements.GetSize(); }

		MaterialElementRequirement * GetMaterialRequirements( void );
	
	private:

		PSX_MakeStoragePoolFriend( Effect );

		Effect( void );

		EErrorCode::Type Initialize( void );

		void Cleanup( void );

	private:

		// File parsing methods
		EErrorCode::Type ProcessEffect( XMLElementPtr pElem );

		EErrorCode::Type ProcessInfo( XMLElementPtr pElem );

		EErrorCode::Type ProcessRequirements( XMLElementPtr pElem );

	public:

		//typedef EffectDesc::EffectID EffectID;
		typedef Array<GeometryElementRequirement> GeometryRequirementList;
		typedef Array<MaterialElementRequirement> MaterialRequirementList;
	
	private:

		EffectDesc m_desc;
		//RenderPasses m_renderPasses;
		RenderTechnique			*m_pTechnique;
		TechniquePriority		m_techniquePriority; // Cache the technique's priority
		GeometryRequirementList m_geometryRequirements;
		MaterialRequirementList m_materialRequirements;
	};
}

#endif /* _PSX_RENDER_TECHINIQUE_H_ */